package com.fxd.factory;

import com.fxd.domain.Account;
import com.fxd.service.IAccountService;
import com.fxd.uitls.transactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @auther fuxudong
 * @date 2021/1/26 - 10:48
 * 用于创建service的代理对象的工厂
 */
public class beanFactory {

    private IAccountService accountService;

    private transactionManager txManager;

    public void setTxManager(transactionManager txManager) {
        this.txManager = txManager;
    }

    public final void setAccountService(IAccountService accountService) {
        this.accountService = accountService;
    }

    /**
     * 获取service代理对象
     * @return
     */
    public IAccountService getAccountService() {
        IAccountService proxyService =(IAccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(),
                accountService.getClass().getInterfaces(), new InvocationHandler() {
                    /**
                     * 添加事物的支持
                     * @param proxy
                     * @param method
                     * @param args
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    //整个invoke方法在执行就是环绕通知
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("动态代理对象执行了");
                        Object result = null;
                        try {
                            //1,开启事物
                            txManager.begin();//前置通知
                            //2,执行操作
                            result = method.invoke(accountService, args);//在环绕通知中有明确的切入点方法调用
                            //3,提交事物
                            txManager.commit();//后置通知
                            //4,返回结果
                            return result;
                        } catch (Exception e) {
                            //5,回滚操作
                            System.out.println("回滚操作执行了");
                            txManager.rollback();
                            throw new RuntimeException(e);//异常通知
                        } finally {
                            //6,释放连接
                            txManager.release();//最终通知
                        }
                    }

                });
        return proxyService;

    }
}
